package com.terracloud.server.controller;

import com.terracloud.server.common.data.TenantGroup;
import com.terracloud.server.common.data.exception.ThingsboardException;
import com.terracloud.server.common.data.id.TenantGroupId;
import com.terracloud.server.common.data.id.TenantId;
import com.terracloud.server.common.data.page.PageData;
import com.terracloud.server.common.data.page.PageLink;
import com.terracloud.server.queue.util.TbCoreComponent;
import com.terracloud.server.service.entitiy.tenant.group.TbTenantGroupService;
import com.terracloud.server.service.security.permission.Operation;
import com.terracloud.server.vo.TenantGroupRelationUpdateVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import static com.terracloud.server.controller.ControllerConstants.DEVICE_GROUP_ID;

/**
 *
 * @author chenhainan
 * @since 2025/10/11
 */
@RestController
@TbCoreComponent
@RequestMapping("/api")
@RequiredArgsConstructor
@Slf4j
public class TenantGroupController extends BaseController {


    @GetMapping("/tenantGroups")
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
    public PageData<TenantGroup> getTenantGroups(
            @RequestParam int pageSize,
            @RequestParam int page,
            @RequestParam(required = false) String textSearch,
            @RequestParam(required = false) String sortProperty,
            @RequestParam(required = false) String sortOrder
    ) throws ThingsboardException {
        TenantId tenantId = getCurrentUser().getTenantId();
        PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
        return tenantGroupService.findTenantGroups(tenantId, pageLink);
    }

    @PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
    @PostMapping(value = "/tenantGroup")
    public TenantGroup saveTenantGroup(@RequestBody TenantGroup tenantGroup) throws ThingsboardException {
        final var currentUser = getCurrentUser();
        tenantGroup.setTenantId(currentUser.getTenantId());
        return tenantGroupService.saveTenantGroup(tenantGroup, currentUser);
    }

    @GetMapping(value = "/tenantGroup/{tenantGroupId}")
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
    public TenantGroup getTenantGroup(@PathVariable("tenantGroupId") String strTenantGroupId) throws ThingsboardException {
        return tenantGroupService.findTenantGroupInfoById(getCurrentUser().getTenantId(), TenantGroupId.fromString(strTenantGroupId));
    }


    @PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
    @DeleteMapping(value = "/tenantGroup/{tenantGroupId}")
    public void deleteTenantGroup(@PathVariable("tenantGroupId") String strTenantGroupId) throws ThingsboardException {
        checkParameter(DEVICE_GROUP_ID, strTenantGroupId);
        final var tenantGroupId = new TenantGroupId(toUUID(strTenantGroupId));
        final var tenantGroup = checkTenantGroupId(tenantGroupId, Operation.DELETE);
        tenantGroupService.delete(tenantGroup, getCurrentUser());
    }


    @PostMapping("/tenantGroup/addTenant")
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
    public TenantGroup addTenantToGroup(@Validated @RequestBody TenantGroupRelationUpdateVo tenantGroupRelationUpdateVo) throws ThingsboardException {
        checkTenantGroupId(new TenantGroupId(tenantGroupRelationUpdateVo.getTenantGroupId()), Operation.WRITE);
        tenantGroupService.addTenantToGroup(getCurrentUser(), tenantGroupRelationUpdateVo);
        return tenantGroupService.findTenantGroupInfoById(getCurrentUser().getTenantId(), new TenantGroupId(tenantGroupRelationUpdateVo.getTenantGroupId()));
    }

    @PostMapping("/tenantGroup/delTenant")
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
    public TenantGroup removeTenantFromGroup(@Validated @RequestBody TenantGroupRelationUpdateVo tenantGroupRelationUpdateVo) throws ThingsboardException {
        checkTenantGroupId(new TenantGroupId(tenantGroupRelationUpdateVo.getTenantGroupId()), Operation.WRITE);
        tenantGroupService.removeTenantFromGroup(getCurrentUser(), tenantGroupRelationUpdateVo);
        return tenantGroupService.findTenantGroupInfoById(getCurrentUser().getTenantId(), new TenantGroupId(tenantGroupRelationUpdateVo.getTenantGroupId()));
    }

}
